<?php
/**
 * 用户验证器
 *
 * @author Claude Code
 * @since 2025-11-03
 */

namespace app\validate;

use think\Validate;

/**
 * 用户数据验证
 *
 * 验证规则：
 * 1. 创建用户验证
 * 2. 更新用户验证
 * 3. 密码修改验证
 * 4. 登录验证
 */
class UserValidate extends Validate
{
    /**
     * 验证规则
     */
    protected $rule = [
        // 基本信息
        'name' => 'require|max:50',
        'username' => 'require|alphaNum|length:3,50|unique:admin',
        'email' => 'email|max:100',
        'mobile' => 'mobile|length:11',
        'password' => 'alphaNum|length:6,20',
        'reg_pwd' => 'alphaNum|length:6,20',

        // 组织信息
        'did' => 'require|number|gt:0',
        'position_id' => 'require|number|gt:0',
        'group_id' => 'number|gt:0',
        'pid' => 'number|egt:0',

        // 个人资料
        'sex' => 'in:0,1,2',
        'birthday' => 'date',
        'idcard' => 'idCard',
        'nation' => 'max:20',
        'education' => 'max:50',
        'graduate_school' => 'max:100',
        'speciality' => 'max:100',
        'native_place' => 'max:100',

        // 联系信息
        'home_address' => 'max:255',
        'current_address' => 'max:255',
        'contact' => 'max:50',
        'contact_mobile' => 'mobile|length:11',

        // 系统信息
        'status' => 'in:-1,0,1,2',
        'user_type' => 'in:1,2',
        'is_lock' => 'in:0,1',
        'is_hide' => 'in:0,1',

        // 其他
        'job_number' => 'max:50',
        'entry_time' => 'date',
        'file_ids' => 'max:500',
        'desc' => 'max:1000',
    ];

    /**
     * 验证提示信息
     */
    protected $message = [
        // 基本信息
        'name.require' => '用户姓名不能为空',
        'name.max' => '用户姓名长度不能超过50个字符',
        'username.require' => '用户名不能为空',
        'username.alphaNum' => '用户名只能是字母和数字',
        'username.length' => '用户名长度在3到50个字符之间',
        'username.unique' => '用户名已存在',
        'email' => '邮箱格式不正确',
        'email.max' => '邮箱长度不能超过100个字符',
        'mobile' => '手机号格式不正确',
        'mobile.length' => '手机号长度必须为11位',
        'password' => '密码只能是字母和数字，长度在6到20个字符之间',
        'reg_pwd' => '初始密码只能是字母和数字，长度在6到20个字符之间',

        // 组织信息
        'did.require' => '请选择部门',
        'did.number' => '部门ID必须是数字',
        'did.gt' => '请选择部门',
        'position_id.require' => '请选择职位',
        'position_id.number' => '职位ID必须是数字',
        'position_id.gt' => '请选择职位',
        'group_id.number' => '权限组ID必须是数字',
        'group_id.gt' => '权限组ID必须大于0',
        'pid.number' => '上级ID必须是数字',
        'pid.egt' => '上级ID必须大于等于0',

        // 个人资料
        'sex' => '性别值不正确',
        'birthday' => '生日格式不正确',
        'idcard' => '身份证格式不正确',
        'nation' => '民族长度不能超过20个字符',
        'education' => '学历长度不能超过50个字符',
        'graduate_school' => '毕业学校长度不能超过100个字符',
        'speciality' => '专业长度不能超过100个字符',
        'native_place' => '籍贯长度不能超过100个字符',

        // 联系信息
        'home_address' => '家庭地址长度不能超过255个字符',
        'current_address' => '现居地址长度不能超过255个字符',
        'contact' => '紧急联系人长度不能超过50个字符',
        'contact_mobile' => '紧急联系人电话格式不正确',
        'contact_mobile.length' => '紧急联系人电话长度必须为11位',

        // 系统信息
        'status' => '状态值不正确',
        'user_type' => '用户类型值不正确',
        'is_lock' => '锁定状态值不正确',
        'is_hide' => '隐藏状态值不正确',

        // 其他
        'job_number' => '工号长度不能超过50个字符',
        'entry_time' => '入职日期格式不正确',
        'file_ids' => '附件ID字符串过长',
        'desc' => '个人简介长度不能超过1000个字符',
    ];

    /**
     * 验证场景
     */
    protected $scene = [
        // 场景：添加用户
        'add' => [
            'name', 'username', 'email', 'mobile', 'password',
            'did', 'position_id', 'group_id', 'sex', 'birthday',
            'nation', 'education', 'graduate_school', 'native_place',
            'home_address', 'current_address', 'contact', 'contact_mobile',
            'status', 'user_type', 'job_number', 'entry_time', 'desc'
        ],

        // 场景：编辑用户
        'edit' => [
            'name', 'email', 'mobile', 'did', 'position_id', 'group_id',
            'sex', 'birthday', 'nation', 'education', 'graduate_school',
            'native_place', 'home_address', 'current_address', 'contact',
            'contact_mobile', 'status', 'user_type', 'job_number',
            'entry_time', 'desc'
        ],

        // 场景：修改密码
        'password' => [
            'password' => 'require|alphaNum|length:6,20'
        ],

        // 场景：重置密码
        'reset_password' => [
            'reg_pwd' => 'require|alphaNum|length:6,20'
        ],

        // 场景：修改基本信息
        'profile' => [
            'name', 'email', 'mobile', 'sex', 'birthday', 'nation',
            'education', 'graduate_school', 'native_place', 'home_address',
            'current_address', 'contact', 'contact_mobile'
        ],

        // 场景：登录
        'login' => [
            'username' => 'require',
            'password' => 'require'
        ],

        // 场景：设置状态
        'set_status' => [
            'status' => 'require|in:-1,0,1,2'
        ],

        // 场景：设置锁定状态
        'set_lock' => [
            'is_lock' => 'require|in:0,1'
        ],

        // 场景：批量导入
        'import' => [
            'name' => 'require',
            'username' => 'require|alphaNum|length:3,50',
            'email' => 'email',
            'mobile' => 'mobile',
            'did' => 'require|number|gt:0',
            'position_id' => 'require|number|gt:0'
        ],

        // 场景：搜索
        'search' => [
            'keywords' => 'max:50',
            'name' => 'max:50',
            'username' => 'alphaNum|length:3,50',
            'mobile' => 'mobile',
            'status' => 'in:-1,0,1,2',
            'user_type' => 'in:1,2',
            'did' => 'number|gt:0',
            'position_id' => 'number|gt:0',
            'sex' => 'in:0,1,2',
            'start_date' => 'date',
            'end_date' => 'date'
        ],

        // 场景：修改头像
        'avatar' => [
            'thumb' => 'require|max:255'
        ],

        // 场景：设置隐藏状态
        'set_hide' => [
            'is_hide' => 'require|in:0,1'
        ]
    ];

    /**
     * 扩展验证方法
     */
    protected function checkIdCard($value, $rule, $data = [])
    {
        if (empty($value)) {
            return true;
        }

        // 简化的身份证验证
        return preg_match('/^[1-9]\d{5}(18|19|20)\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}[0-9Xx]$/', $value);
    }

    /**
     * 自定义验证：检查用户名是否在黑名单中
     */
    protected function checkUsernameBlacklist($value, $rule, $data = [])
    {
        $blacklist = ['admin', 'root', 'system', 'test', 'guest'];
        return !in_array(strtolower($value), $blacklist);
    }

    /**
     * 自定义验证：检查手机号是否在黑名单中
     */
    protected function checkMobileBlacklist($value, $rule, $data = [])
    {
        $blacklist = ['13800138000', '13900139000'];
        return !in_array($value, $blacklist);
    }

    /**
     * 自定义验证：检查邮箱域名是否允许
     */
    protected function checkEmailDomain($value, $rule, $data = [])
    {
        if (empty($value)) {
            return true;
        }

        $allowedDomains = ['example.com', 'test.com'];
        $domain = substr(strrchr($value, '@'), 1);
        return in_array($domain, $allowedDomains) || empty($rule);
    }

    /**
     * 自定义验证：检查部门是否存在且启用
     */
    protected function checkDepartment($value, $rule, $data = [])
    {
        if (empty($value)) {
            return true;
        }

        $department = \app\model\admin\Department::find($value);
        return $department && $department['status'] > 0;
    }

    /**
     * 自定义验证：检查职位是否存在且启用
     */
    protected function checkPosition($value, $rule, $data = [])
    {
        if (empty($value)) {
            return true;
        }

        $position = \app\model\admin\Position::find($value);
        return $position && $position['status'] > 0;
    }

    /**
     * 自定义验证：检查权限组是否存在
     */
    protected function checkGroup($value, $rule, $data = [])
    {
        if (empty($value)) {
            return true;
        }

        $group = \app\model\admin\AdminGroup::find($value);
        return (bool) $group;
    }

    /**
     * 自定义验证：检查上级用户是否存在
     */
    protected function checkParent($value, $rule, $data = [])
    {
        if (empty($value) || $value == ($data['id'] ?? 0)) {
            return true;
        }

        $parent = \app\model\admin\User::find($value);
        return (bool) $parent;
    }

    /**
     * 自定义验证：检查用户名是否包含敏感词
     */
    protected function checkUsernameSensitive($value, $rule, $data = [])
    {
        $sensitiveWords = ['admin', 'root', 'system', 'test'];
        foreach ($sensitiveWords as $word) {
            if (stripos($value, $word) !== false) {
                return false;
            }
        }
        return true;
    }

    /**
     * 自定义验证：检查生日是否合理
     */
    protected function checkBirthday($value, $rule, $data = [])
    {
        if (empty($value)) {
            return true;
        }

        $birthday = strtotime($value);
        $minAge = strtotime('-100 years');
        $maxAge = strtotime('-16 years');

        return $birthday >= $minAge && $birthday <= $maxAge;
    }

    /**
     * 自定义验证：检查入职日期是否合理
     */
    protected function checkEntryTime($value, $rule, $data = [])
    {
        if (empty($value)) {
            return true;
        }

        $entryTime = strtotime($value);
        $maxFuture = strtotime('+1 year');
        $minPast = strtotime('-50 years');

        return $entryTime <= $maxFuture && $entryTime >= $minPast;
    }

    /**
     * 自定义验证：检查文件ID格式
     */
    protected function checkFileIds($value, $rule, $data = [])
    {
        if (empty($value)) {
            return true;
        }

        // 检查是否是逗号分隔的数字ID
        return preg_match('/^\d+(,\d+)*$/', $value);
    }

    /**
     * 验证前处理
     * 可以在这里对数据进行预处理
     */
    protected function beforeCheck($data)
    {
        // 清理数据
        if (isset($data['name'])) {
            $data['name'] = trim($data['name']);
        }

        if (isset($data['username'])) {
            $data['username'] = trim($data['username']);
        }

        if (isset($data['email'])) {
            $data['email'] = trim($data['email']);
        }

        if (isset($data['mobile'])) {
            $data['mobile'] = trim($data['mobile']);
        }

        return $data;
    }

    /**
     * 自定义验证：验证部门是否允许删除
     */
    protected function checkDepartmentDeletable($value, $rule, $data = [])
    {
        if (empty($value)) {
            return true;
        }

        // 检查是否有关联的用户
        $userCount = \app\model\admin\User::where('did', $value)->count();
        if ($userCount > 0) {
            return false;
        }

        return true;
    }

    /**
     * 自定义验证：验证职位是否允许删除
     */
    protected function checkPositionDeletable($value, $rule, $data = [])
    {
        if (empty($value)) {
            return true;
        }

        // 检查是否有关联的用户
        $userCount = \app\model\admin\User::where('position_id', $value)->count();
        if ($userCount > 0) {
            return false;
        }

        return true;
    }

    /**
     * 自定义验证：检查用户是否允许删除
     */
    protected function checkUserDeletable($value, $rule, $data = [])
    {
        if (empty($value)) {
            return true;
        }

        // 检查是否有下级
        $childCount = \app\model\admin\User::where('pid', $value)->count();
        if ($childCount > 0) {
            return false;
        }

        // 检查是否有关联的案件
        $caseCount = Db::table('oa_lawcase')
            ->where('admin_id', $value)
            ->whereOr('lawyer_id', $value)
            ->count();
        if ($caseCount > 0) {
            return false;
        }

        return true;
    }
}
